{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/eBRPvWB.png)\n",
    "\n",
    "# Practical PyTorch: Classifying Names with a Character-Level RNN\n",
    "\n",
    "We will be building and training a basic character-level RNN to classify words. A character-level RNN reads words as a series of characters - outputting a prediction and \"hidden state\" at each step, feeding its previous hidden state into each next step. We take the final prediction to be the output, i.e. which class the word belongs to.\n",
    "\n",
    "Specifically, we'll train on a few thousand surnames from 18 languages of origin, and predict which language a name is from based on the spelling:\n",
    "\n",
    "```\n",
    "$ python predict.py Hinton\n",
    "(-0.47) Scottish\n",
    "(-1.52) English\n",
    "(-3.57) Irish\n",
    "\n",
    "$ python predict.py Schmidhuber\n",
    "(-0.19) German\n",
    "(-2.48) Czech\n",
    "(-2.68) Dutch\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Recommended Reading\n",
    "\n",
    "I assume you have at least installed PyTorch, know Python, and understand Tensors:\n",
    "\n",
    "* http://pytorch.org/ For installation instructions\n",
    "* [Deep Learning with PyTorch: A 60-minute Blitz](http://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html) to get started with PyTorch in general\n",
    "* [jcjohnson's PyTorch examples](https://github.com/jcjohnson/pytorch-examples) for an in depth overview\n",
    "* [Introduction to PyTorch for former Torchies](https://github.com/pytorch/tutorials/blob/master/Introduction%20to%20PyTorch%20for%20former%20Torchies.ipynb) if you are former Lua Torch user\n",
    "\n",
    "It would also be useful to know about RNNs and how they work:\n",
    "\n",
    "* [The Unreasonable Effectiveness of Recurrent Neural Networks](http://karpathy.github.io/2015/05/21/rnn-effectiveness/) shows a bunch of real life examples\n",
    "* [Understanding LSTM Networks](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) is about LSTMs specifically but also informative about RNNs in general"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preparing the Data\n",
    "\n",
    "Included in the `data/names` directory are 18 text files named as \"[Language].txt\". Each file contains a bunch of names, one name per line, mostly romanized (but we still need to convert from Unicode to ASCII).\n",
    "\n",
    "We'll end up with a dictionary of lists of names per language, `{language: [names ...]}`. The generic variables \"category\" and \"line\" (for language and name in our case) are used for later extensibility."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['../data/names/Arabic.txt', '../data/names/Chinese.txt', '../data/names/Czech.txt', '../data/names/Dutch.txt', '../data/names/English.txt', '../data/names/French.txt', '../data/names/German.txt', '../data/names/Greek.txt', '../data/names/Irish.txt', '../data/names/Italian.txt', '../data/names/Japanese.txt', '../data/names/Korean.txt', '../data/names/Polish.txt', '../data/names/Portuguese.txt', '../data/names/Russian.txt', '../data/names/Scottish.txt', '../data/names/Spanish.txt', '../data/names/Vietnamese.txt']\n"
     ]
    }
   ],
   "source": [
    "import glob\n",
    "\n",
    "all_filenames = glob.glob('../data/names/*.txt')\n",
    "print(all_filenames)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Slusarski\n"
     ]
    }
   ],
   "source": [
    "import unicodedata\n",
    "import string\n",
    "\n",
    "all_letters = string.ascii_letters + \" .,;'\"\n",
    "n_letters = len(all_letters)\n",
    "\n",
    "# Turn a Unicode string to plain ASCII, thanks to http://stackoverflow.com/a/518232/2809427\n",
    "def unicode_to_ascii(s):\n",
    "    return ''.join(\n",
    "        c for c in unicodedata.normalize('NFD', s)\n",
    "        if unicodedata.category(c) != 'Mn'\n",
    "        and c in all_letters\n",
    "    )\n",
    "\n",
    "print(unicode_to_ascii('Ślusàrski'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "n_categories = 18\n"
     ]
    }
   ],
   "source": [
    "# Build the category_lines dictionary, a list of names per language\n",
    "category_lines = {}\n",
    "all_categories = []\n",
    "\n",
    "# Read a file and split into lines\n",
    "def readLines(filename):\n",
    "    lines = open(filename).read().strip().split('\\n')\n",
    "    return [unicode_to_ascii(line) for line in lines]\n",
    "\n",
    "for filename in all_filenames:\n",
    "    category = filename.split('/')[-1].split('.')[0]\n",
    "    all_categories.append(category)\n",
    "    lines = readLines(filename)\n",
    "    category_lines[category] = lines\n",
    "\n",
    "n_categories = len(all_categories)\n",
    "print('n_categories =', n_categories)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we have `category_lines`, a dictionary mapping each category (language) to a list of lines (names). We also kept track of `all_categories` (just a list of languages) and `n_categories` for later reference."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Abandonato', 'Abatangelo', 'Abatantuono', 'Abate', 'Abategiovanni']\n"
     ]
    }
   ],
   "source": [
    "print(category_lines['Italian'][:5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Turning Names into Tensors\n",
    "\n",
    "Now that we have all the names organized, we need to turn them into Tensors to make any use of them.\n",
    "\n",
    "To represent a single letter, we use a \"one-hot vector\" of size `<1 x n_letters>`. A one-hot vector is filled with 0s except for a 1 at index of the current letter, e.g. `\"b\" = <0 1 0 0 0 ...>`.\n",
    "\n",
    "To make a word we join a bunch of those into a 2D matrix `<line_length x 1 x n_letters>`.\n",
    "\n",
    "That extra 1 dimension is because PyTorch assumes everything is in batches - we're just using a batch size of 1 here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "\n",
    "# Just for demonstration, turn a letter into a <1 x n_letters> Tensor\n",
    "def letter_to_tensor(letter):\n",
    "    tensor = torch.zeros(1, n_letters)\n",
    "    letter_index = all_letters.find(letter)\n",
    "    tensor[0][letter_index] = 1\n",
    "    return tensor\n",
    "\n",
    "# Turn a line into a <line_length x 1 x n_letters>,\n",
    "# or an array of one-hot letter vectors\n",
    "def line_to_tensor(line):\n",
    "    tensor = torch.zeros(len(line), 1, n_letters)\n",
    "    for li, letter in enumerate(line):\n",
    "        letter_index = all_letters.find(letter)\n",
    "        tensor[li][0][letter_index] = 1\n",
    "    return tensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "Columns 0 to 12 \n",
      "    0     0     0     0     0     0     0     0     0     0     0     0     0\n",
      "\n",
      "Columns 13 to 25 \n",
      "    0     0     0     0     0     0     0     0     0     0     0     0     0\n",
      "\n",
      "Columns 26 to 38 \n",
      "    0     0     0     0     0     0     0     0     0     1     0     0     0\n",
      "\n",
      "Columns 39 to 51 \n",
      "    0     0     0     0     0     0     0     0     0     0     0     0     0\n",
      "\n",
      "Columns 52 to 56 \n",
      "    0     0     0     0     0\n",
      "[torch.FloatTensor of size 1x57]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(letter_to_tensor('J'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5, 1, 57])\n"
     ]
    }
   ],
   "source": [
    "print(line_to_tensor('Jones').size())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Creating the Network\n",
    "\n",
    "Before autograd, creating a recurrent neural network in Torch involved cloning the parameters of a layer over several timesteps. The layers held hidden state and gradients which are now entirely handled by the graph itself. This means you can implement a RNN in a very \"pure\" way, as regular feed-forward layers.\n",
    "\n",
    "This RNN module (mostly copied from [the PyTorch for Torch users tutorial](https://github.com/pytorch/tutorials/blob/master/Introduction%20to%20PyTorch%20for%20former%20Torchies.ipynb)) is just 2 linear layers which operate on an input and hidden state, with a LogSoftmax layer after the output.\n",
    "\n",
    "![](https://i.imgur.com/Z2xbySO.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "from torch.autograd import Variable\n",
    "\n",
    "class RNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, output_size):\n",
    "        super(RNN, self).__init__()\n",
    "        \n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.output_size = output_size\n",
    "        \n",
    "        self.i2h = nn.Linear(input_size + hidden_size, hidden_size)\n",
    "        self.i2o = nn.Linear(input_size + hidden_size, output_size)\n",
    "        self.softmax = nn.LogSoftmax()\n",
    "    \n",
    "    def forward(self, input, hidden):\n",
    "        combined = torch.cat((input, hidden), 1)\n",
    "        hidden = self.i2h(combined)\n",
    "        output = self.i2o(combined)\n",
    "        output = self.softmax(output)\n",
    "        return output, hidden\n",
    "\n",
    "    def init_hidden(self):\n",
    "        return Variable(torch.zeros(1, self.hidden_size))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Manually testing the network\n",
    "\n",
    "With our custom `RNN` class defined, we can create a new instance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "n_hidden = 128\n",
    "rnn = RNN(n_letters, n_hidden, n_categories)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To run a step of this network we need to pass an input (in our case, the Tensor for the current letter) and a previous hidden state (which we initialize as zeros at first). We'll get back the output (probability of each language) and a next hidden state (which we keep for the next step).\n",
    "\n",
    "Remember that PyTorch modules operate on Variables rather than straight up Tensors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "output.size = torch.Size([1, 18])\n"
     ]
    }
   ],
   "source": [
    "input = Variable(letter_to_tensor('A'))\n",
    "hidden = rnn.init_hidden()\n",
    "\n",
    "output, next_hidden = rnn(input, hidden)\n",
    "print('output.size =', output.size())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the sake of efficiency we don't want to be creating a new Tensor for every step, so we will use `line_to_tensor` instead of `letter_to_tensor` and use slices. This could be further optimized by pre-computing batches of Tensors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Variable containing:\n",
      "\n",
      "Columns 0 to 9 \n",
      "-2.8658 -2.8801 -2.7945 -2.9082 -2.8309 -2.9718 -2.9366 -2.9416 -2.7900 -2.8467\n",
      "\n",
      "Columns 10 to 17 \n",
      "-2.9495 -2.9496 -2.8707 -2.8984 -2.8147 -2.9442 -2.9257 -2.9363\n",
      "[torch.FloatTensor of size 1x18]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "input = Variable(line_to_tensor('Albert'))\n",
    "hidden = Variable(torch.zeros(1, n_hidden))\n",
    "\n",
    "output, next_hidden = rnn(input[0], hidden)\n",
    "print(output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see the output is a `<1 x n_categories>` Tensor, where every item is the likelihood of that category (higher is more likely)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preparing for Training\n",
    "\n",
    "Before going into training we should make a few helper functions. The first is to interpret the output of the network, which we know to be a likelihood of each category. We can use `Tensor.topk` to get the index of the greatest value:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Irish', 8)\n"
     ]
    }
   ],
   "source": [
    "def category_from_output(output):\n",
    "    top_n, top_i = output.data.topk(1) # Tensor out of Variable with .data\n",
    "    category_i = top_i[0][0]\n",
    "    return all_categories[category_i], category_i\n",
    "\n",
    "print(category_from_output(output))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also want a quick way to get a training example (a name and its language):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "category = Italian / line = Campana\n",
      "category = Korean / line = Koo\n",
      "category = Irish / line = Mochan\n",
      "category = Japanese / line = Kitabatake\n",
      "category = Vietnamese / line = an\n",
      "category = Korean / line = Kwak\n",
      "category = Portuguese / line = Campos\n",
      "category = Vietnamese / line = Chung\n",
      "category = Japanese / line = Ise\n",
      "category = Dutch / line = Romijn\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "\n",
    "def random_training_pair():                                                                                                               \n",
    "    category = random.choice(all_categories)\n",
    "    line = random.choice(category_lines[category])\n",
    "    category_tensor = Variable(torch.LongTensor([all_categories.index(category)]))\n",
    "    line_tensor = Variable(line_to_tensor(line))\n",
    "    return category, line, category_tensor, line_tensor\n",
    "\n",
    "for i in range(10):\n",
    "    category, line, category_tensor, line_tensor = random_training_pair()\n",
    "    print('category =', category, '/ line =', line)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Training the Network\n",
    "\n",
    "Now all it takes to train this network is show it a bunch of examples, have it make guesses, and tell it if it's wrong.\n",
    "\n",
    "For the [loss function `nn.NLLLoss`](http://pytorch.org/docs/nn.html#nllloss) is appropriate, since the last layer of the RNN is `nn.LogSoftmax`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "criterion = nn.NLLLoss()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also create an \"optimizer\" which updates the parameters of our model according to its gradients. We will use the vanilla SGD algorithm with a low learning rate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "learning_rate = 0.005 # If you set this too high, it might explode. If too low, it might not learn\n",
    "optimizer = torch.optim.SGD(rnn.parameters(), lr=learning_rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each loop of training will:\n",
    "\n",
    "* Create input and target tensors\n",
    "* Create a zeroed initial hidden state\n",
    "* Read each letter in and\n",
    "    * Keep hidden state for next letter\n",
    "* Compare final output to target\n",
    "* Back-propagate\n",
    "* Return the output and loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def train(category_tensor, line_tensor):\n",
    "    rnn.zero_grad()\n",
    "    hidden = rnn.init_hidden()\n",
    "    \n",
    "    for i in range(line_tensor.size()[0]):\n",
    "        output, hidden = rnn(line_tensor[i], hidden)\n",
    "\n",
    "    loss = criterion(output, category_tensor)\n",
    "    loss.backward()\n",
    "\n",
    "    optimizer.step()\n",
    "\n",
    "    return output, loss.data[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we just have to run that with a bunch of examples. Since the `train` function returns both the output and loss we can print its guesses and also keep track of loss for plotting. Since there are 1000s of examples we print only every `print_every` time steps, and take an average of the loss."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5000 5% (0m 7s) 2.7940 Neil / Chinese ✗ (Irish)\n",
      "10000 10% (0m 14s) 2.7166 O'Kelly / English ✗ (Irish)\n",
      "15000 15% (0m 23s) 1.1694 Vescovi / Italian ✓\n",
      "20000 20% (0m 31s) 2.1433 Mikhailjants / Greek ✗ (Russian)\n",
      "25000 25% (0m 40s) 2.0299 Planick / Russian ✗ (Czech)\n",
      "30000 30% (0m 48s) 1.9862 Cabral / French ✗ (Portuguese)\n",
      "35000 35% (0m 55s) 1.5634 Espina / Spanish ✓\n",
      "40000 40% (1m 5s) 3.8602 MaxaB / Arabic ✗ (Czech)\n",
      "45000 45% (1m 13s) 3.5599 Sandoval / Dutch ✗ (Spanish)\n",
      "50000 50% (1m 20s) 1.3855 Brown / Scottish ✓\n",
      "55000 55% (1m 27s) 1.6269 Reid / French ✗ (Scottish)\n",
      "60000 60% (1m 35s) 0.4495 Kijek / Polish ✓\n",
      "65000 65% (1m 43s) 1.0269 Young / Scottish ✓\n",
      "70000 70% (1m 50s) 1.9761 Fischer / English ✗ (German)\n",
      "75000 75% (1m 57s) 0.7915 Rudaski / Polish ✓\n",
      "80000 80% (2m 5s) 1.7026 Farina / Portuguese ✗ (Italian)\n",
      "85000 85% (2m 12s) 0.1878 Bakkarevich / Russian ✓\n",
      "90000 90% (2m 19s) 0.1211 Pasternack / Polish ✓\n",
      "95000 95% (2m 25s) 0.6084 Otani / Japanese ✓\n",
      "100000 100% (2m 33s) 0.2713 Alesini / Italian ✓\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "import math\n",
    "\n",
    "n_epochs = 100000\n",
    "print_every = 5000\n",
    "plot_every = 1000\n",
    "\n",
    "# Keep track of losses for plotting\n",
    "current_loss = 0\n",
    "all_losses = []\n",
    "\n",
    "def time_since(since):\n",
    "    now = time.time()\n",
    "    s = now - since\n",
    "    m = math.floor(s / 60)\n",
    "    s -= m * 60\n",
    "    return '%dm %ds' % (m, s)\n",
    "\n",
    "start = time.time()\n",
    "\n",
    "for epoch in range(1, n_epochs + 1):\n",
    "    # Get a random training input and target\n",
    "    category, line, category_tensor, line_tensor = random_training_pair()\n",
    "    output, loss = train(category_tensor, line_tensor)\n",
    "    current_loss += loss\n",
    "    \n",
    "    # Print epoch number, loss, name and guess\n",
    "    if epoch % print_every == 0:\n",
    "        guess, guess_i = category_from_output(output)\n",
    "        correct = '✓' if guess == category else '✗ (%s)' % category\n",
    "        print('%d %d%% (%s) %.4f %s / %s %s' % (epoch, epoch / n_epochs * 100, time_since(start), loss, line, guess, correct))\n",
    "\n",
    "    # Add current loss avg to list of losses\n",
    "    if epoch % plot_every == 0:\n",
    "        all_losses.append(current_loss / plot_every)\n",
    "        current_loss = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting the Results\n",
    "\n",
    "Plotting the historical loss from `all_losses` shows the network learning:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1103a9358>]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAg0AAAFkCAYAAACjCwibAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzt3Xd4VVX2//H3ogiIGjtYEFFHsI1+EymOg9gLjqKCJaKj\nYBccRWcsOFjHPrZRELsIGgsOKjqD6NgbYqKoI1hRVBCswCBNsn5/rORHElLuTW5Jbj6v57kP3nP2\nOWfdE+Su7LP32ubuiIiIiNSlRbYDEBERkaZBSYOIiIgkREmDiIiIJERJg4iIiCRESYOIiIgkREmD\niIiIJERJg4iIiCRESYOIiIgkREmDiIiIJERJg4iIiCQkqaTBzE41s2lmNr/s9bqZ7V/HMbubWbGZ\nLTGzj83suIaFLCIiItmQbE/DV8B5QD5QADwPPGFm21TX2Mw2B54C/gPsCNwM3GVm+9QzXhEREckS\na+iCVWb2A/Bnd7+3mn3XAAe4+28rbCsC8ty9b4MuLCIiIhlV7zENZtbCzI4CVgfeqKFZL+C5Ktue\nAXap73VFREQkO1ole4CZbU8kCW2BhcCh7j6jhuYdgblVts0F1jKzNu6+tIZrrAfsB3wBLEk2RhER\nkWasLbA58Iy7/5DKEyedNAAziPEJecAA4H4z262WxKE+9gMeSOH5REREmpuBwIOpPGHSSYO7/wp8\nXvb2HTPrAZwJnFZN82+BDlW2dQAW1NTLUOYLgHHjxrHNNtWOsZQ0GDZsGDfeeGO2w2hWdM8zT/c8\n83TPM2v69Okcc8wxUPZdmkr16WmoqgXQpoZ9bwAHVNm2LzWPgSi3BGCbbbYhPz+/YdFJwvLy8nS/\nM0z3PPN0zzNP9zxrUv54P6mkwcyuBP4NzALWJLo++hCJAGZ2FbCxu5fXYhgNDCmbRXEPsBfxSEMz\nJ0RERJqYZHsaNgTGABsB84H3gH3d/fmy/R2BTuWN3f0LMzsQuBH4E/A1cIK7V51RISIiIo1cUkmD\nu59Yx/5B1Wx7mSgEJSIiIk2Y1p6Q/6+wsDDbITQ7uueZp3ueebrnuaPBFSHTwczygeLi4mINnhER\nEUlCSUkJBQUFAAXuXpLKc6unQURERBKipEFEREQSoqRBREREEqKkQURERBKipEFEREQSoqRBRERE\nEqKkQURERBKipEFEREQSoqRBREREEqKkQURERBKipEFEREQSoqRBREREEqKkQURERBKipEFEREQS\noqRBREREEqKkQURERBLSqJMG92xHICIiIuUaddIwcWK2IxAREZFyjTppuPlm+OGHbEchIiIi0MiT\nhuXLYfjwbEchIiIi0MiThiFD4I474M03sx2JiIiIJJU0mNkFZvaWmS0ws7lmNsHMtk7guIFm9q6Z\nLTKz2WZ2t5mtW9dxAwZAfj6ceir8+msykYqIiEiqJdvT0Bu4BegJ7A20BiabWbuaDjCzXYExwJ3A\ntsAAoAdwR10Xa9kSRo+G996DkSOTjFRERERSKqmkwd37uvtYd5/u7u8DxwObAQW1HNYLmOnuI939\nS3d/HbidSBzq1L179DSMGAFz5iQTrYiIiKRSQ8c0rA048GMtbd4AOpnZAQBm1gE4HHg60YtccQW0\naQPnndeQUEVERKQh6p00mJkBNwGvuvuHNbUr61k4BnjYzJYBc4CfgKGJXmuddeDKK2HsWHj99fpG\nLCIiIg3RkJ6GUcQYhaNqa2Rm2wI3A5cA+cB+QBfiEUXCBg+GggIYOhRWrKhXvCIiItIA5vWo1Wxm\ntwIHAb3dfVYdbe8H2rr7ERW27Qq8Amzk7nOrOSYfKN5tt93Iy8v7/9t/+glefbWQ0aMLOeWUpMMW\nERHJKUVFRRQVFVXaNn/+fF5++WWAAncvSeX1kk4ayhKGfkAfd/88gfbjgWXufnSFbbsArwKbuPu3\n1RyTDxQXFxeTn59fad/xx8NTT8HHH8O6dU7aFBERaV5KSkooKCiANCQNydZpGAUMBI4GFplZh7JX\n2wptrjSzMRUOmwj0N7NTzaxLWS/DzcCU6hKGulx9NSxbFrMpREREJHOSHdNwKrAW8CIwu8LriApt\nNgI6lb9x9zHA2cAQ4H3gYWA60L8+AXfsCJdeGvUbpk2rzxlERESkPlol09jd60wy3H1QNdtGAikr\nzzR0KNx5Z0zBnDQpVWcVERGR2jTqtSdq0ro1/PWv8Mwz8MEH2Y5GRESkeWiSSQPA4YfDJpvATTdl\nOxIREZHmockmDa1bwxlnwLhxMHeVSZsiIiKSak02aQA4+eRY1Oq227IdiYiISO5r0knDOutEpchR\no2Dx4mxHIyIiktuadNIAcOaZ8P338MAD2Y5EREQktzX5pGGrraBfP7jhBqhHRWwRERFJUJNPGgDO\nPhumT1fNBhERkXTKiaTh97+HnXeO3gYRERFJj5xIGsyit+G55+D997MdjYiISG7KiaQBYMAAaN8e\n/vWvbEciIiKSm3ImaWjdGnr1gtdey3YkIiIiuSlnkgaAXXeF11/XLAoREZF0yLmk4Ycf4KOPsh2J\niIhI7smppKFXL2jRQo8oRERE0iGnkoa11oIddlDSICIikg45lTRAPKJQ0iAiIpJ6OZk0fPwxfPdd\ntiMRERHJLTmZNIB6G0RERFIt55KGzTaDTTdV0iAiIpJqOZc0mGlcg4iISDrkXNIAkTQUF8OSJdmO\nREREJHfkbNKwbBm8/Xa2IxEREckdOZk0/Pa3sXiVHlGIiIikTlJJg5ldYGZvmdkCM5trZhPMbOsE\njlvNzK4wsy/MbImZfW5mx9c76jq0aqXFq0RERFIt2Z6G3sAtQE9gb6A1MNnM2tVx3KPAHsAgYGug\nEEjrChFavEpERCS1WiXT2N37Vnxf1lswDygAXq3uGDPbn0g2tnD3n8s2z0o60iTtuitcdlksXtWt\nW7qvJiIikvsaOqZhbcCBH2tpcxDwNnCemX1tZh+Z2XVm1raB166VFq8SERFJrXonDWZmwE3Aq+7+\nYS1NtyB6GrYDDgHOBAYAI+t77URo8SoREZHUSurxRBWjgG2BXeto1wIoBY529/8BmNnZwKNmdrq7\nL63pwGHDhpGXl1dpW2FhIYWFhQkF+Pvfw+TJCTUVERFpcoqKiigqKqq0bf78+Wm7nnk9Rgqa2a3E\nY4fe7l7r+AQzuw/4nbtvXWFbN+C/wNbu/lk1x+QDxcXFxeTn5ycdX7kHH4SBA+H772G99ep9GhER\nkSajpKSEgoICgAJ3L0nluZN+PFGWMPQD9qgrYSjzGrCxma1eYVtXovfh62Svn4xeveLPKVPSeRUR\nEZHmIdk6DaOAgcDRwCIz61D2aluhzZVmNqbCYQ8CPwD3mtk2ZrYbcC1wd22PJlKhSxfYYAN48810\nXkVERKR5SLan4VRgLeBFYHaF1xEV2mwEdCp/4+6LgH2ImRZTgbHAE8SAyLQyi94GJQ0iIiINl2yd\nhjqTDHcfVM22j4H9krlWqvTqBddcA6WlMQVTRERE6ifnv0Z79YIFC2DGjGxHIiIi0rTlfNLQvXs8\nptAjChERkYbJ+aRhzTVh++2VNIiIiDRUzicNoMGQIiIiqdBskoYPPoCFC7MdiYiISNPVbJIGd3j7\n7WxHIiIi0nQ1i6ShW7dYwEqPKEREROqvWSQNLVpAz55KGkRERBqiWSQNsHIwZD3W5xIRERGaWdIw\nbx588UW2IxEREWmamk3S0LNn/KlHFCIiIvXTbJKG9daDrbZS0iAiIlJfzSZpABV5EhERaYhmlzS8\n8w4sWZLtSERERJqeZpc0LF8eiYOIiIgkp1klDb/9LbRtC1OmZDsSERGRpqdZJQ2tW8csin//O9uR\niIiIND3NKmkAGDQIJk+GTz7JdiQiIiJNS7NLGo48MqZf3nZbtiMRERFpWppd0tC2LZxwAtxzDyxa\nlO1oREREmo5mlzQAnHoqLFgADz6Y7UhERESajmaZNHTpAn/4A4wcqQWsREREEtUskwaAIUNg2jR4\n/fVsRyIiItI0JJU0mNkFZvaWmS0ws7lmNsHMtk7i+F3NbLmZlSQfamrts0+sRTFyZLYjERERaRqS\n7WnoDdwC9AT2BloDk82sXV0HmlkeMAZ4Ltkg06FFCzj9dBg/Hr79NtvRiIiINH5JJQ3u3tfdx7r7\ndHd/Hzge2AwoSODw0cADQKNZMur446FVK7jzzmxHIiIi0vg1dEzD2oADP9bWyMwGAV2ASxt4vZRa\nZx0YOBBuvx1+/TXb0YiIiDRu9U4azMyAm4BX3f3DWtr9BrgSGOjupfW9Xrqcfjp88w385z/ZjkRE\nRKRxa0hPwyhgW+ComhqYWQvikcTF7v5Z+eYGXDPldtoJ1l1Xi1iJiIjUpVV9DjKzW4G+QG93n1NL\n0zWBnYGdzKx8nkKLOIUtA/Z19xdrOnjYsGHk5eVV2lZYWEhhYWF9wq6WGXTvDm+9lbJTioiIZERR\nURFFRUWVts2fPz9t1zNPsrpRWcLQD+jj7p/X0daAbapsHgLsAfQHvnD3xdUclw8UFxcXk5+fn1R8\n9TFiBNxxR8yisEbVDyIiIpKckpISCgoKAArcPaUlDpKt0zAKGAgcDSwysw5lr7YV2lxpZmMAPHxY\n8QXMA5aUzcBYJWHIhh49YN48mDUr25GIiIg0XsmOaTgVWAt4EZhd4XVEhTYbAZ1SEVymdO8ef06d\nmt04REREGrNk6zS0cPeW1bzur9BmkLvvWcs5LnX39D9zSELHjrDpphrXICIiUptmu/ZEVT16qKdB\nRESkNkoaynTvDsXFsGJFtiMRERFpnJQ0lOnRAxYuhI8+ynYkIiIijZOShjIFZatn6BGFiIhI9ZQ0\nlMnLg65dNRhSRESkJkoaKtBgSBERkZopaaige3eYNg2WLs12JCIiIo2PkoYKevSAZcvgvfeyHYmI\niEjjo6Shgh13hFat9IhCRESkOkoaKmjbNhIHDYYUERFZlZKGKrp3V0+DiIhIdZQ0VNG9O0yfHoWe\nREREZCUlDVX06AHuUVJaREREVlLSUMU220D79npEISIiUpWShipatoyS0hoMKSIiUpmShmp07w4v\nvABvvpntSERERBoPJQ3VOOMM2Hxz+N3vYOhQWLAg2xGJiIhkn5KGanTuHL0MN9wA990X4xwmTMh2\nVCIiItmlpKEGrVrBWWfBhx9Cfj4cdhj87W/ZjkpERCR7lDTUYbPN4Mkn4cwz4dpr4eefsx2RiIhI\ndihpSIAZnH9+LGY1cmS2oxEREckOJQ0J6tgRBg+Gm26CX37JdjQiIiKZp6QhCX/5C/z0E9x1V7Yj\nERERyTwlDUno0gUKC+G66+JRhYiISHOSVNJgZheY2VtmtsDM5prZBDPbuo5jDjWzyWY2z8zmm9nr\nZrZvw8LOnvPPh6+/hgceyHYkIiIimZVsT0Nv4BagJ7A30BqYbGbtajlmN2AycACQD7wATDSzHZMP\nN/u22w769YOrr4YVK7IdjYiISOa0Sqaxu/et+N7MjgfmAQXAqzUcM6zKpgvNrB9wEDAtmes3Fhdc\nAL16RcGnAQOyHY2IiEhmNHRMw9qAAz8meoCZGbBmMsc0Nj17wp57wpVXxjLaIiIizUG9k4ayL/+b\ngFfd/cMkDv0L0B54pL7XbgyGD4d33oFHmvSnEBERSVxSjyeqGAVsC+ya6AFmdjQwAjjY3b+vq/2w\nYcPIy8urtK2wsJDCwsIkQ029vfaK0tJnnBH/vf762Y5IRESam6KiIoqKiiptmz9/ftquZ16P/nUz\nu5UYk9Db3WcleMxRwF3AAHefVEfbfKC4uLiY/Pz8pOPLlG+/hW23hb59Ydy4bEcjIiICJSUlFBQU\nABS4e0kqz53044myhKEfsEcSCUMhcDdwVF0JQ1PSsWNUiHzgAXjqqWxHIyIikl7J1mkYBQwEjgYW\nmVmHslfbCm2uNLMxFd4fDYwBzgGmVjhmrdR8hOw69ljYf3849VRIY4+QiIhI1iXb03AqsBbwIjC7\nwuuICm02AjpVeH8S0BIYWeWYm+oVcSNjBrffDgsWRJlpERGRXJVsnYY6kwx3H1Tl/R7JBtXUbLZZ\nLJt92mlw5JExMFJERCTXaO2JFDn5ZNh9dzjrrGxHIiIikh5KGlKkRQs46ST44AP4vs7JpCIiIk2P\nkoYU6tkz/nzrrezGISIikg5KGlJoiy2iyNOUKdmOREREJPWUNKSQWfQ2vPlmtiMRERFJPSUNKdaz\nZzyeKC3NdiQiIiKppaQhxXr1gp9/hk8+yXYkIiIiqaWkIcW6d48/Na5BRERyjZKGFFt7bejWTeMa\nREQk9yhpSINevdTTICIiuUdJQxr07AnvvQeLF2c7EhERkdRR0pAGPXvCr79CSUpXMRcREckuJQ1p\nsMMO0K6dxjWIiEhuUdKQBq1awc47a1yDiIjkFiUNadKzp5IGERHJLUoa0qRnT5g1C+bMyXYkIiIi\nqaGkIU169Yo/q/Y2PPssdOkCL76Y8ZBEREQaRElDmmy6KWy8ceWk4cMPYcAAmDcPDj003ouIiDQV\nShrSqOK4hnnz4MADoXNn+Ogj6NQJDjhAjy9ERKTpUNKQRr16wdSpsGgRHHJIFHt66qnohfjXv2DF\nikgkFi7MdqQiIiJ1U9KQRj17wv/+B/vtB++8A08+CZttFvvKE4dPP4UjjohiUCIiIo2ZkoY0KiiA\nFi3gtddg7Fjo0aPy/t/+Fh57DJ57DoYOzU6MIiIiiWqV7QBy2RprwMknw3bbxQDI6uyzD4weDSee\nCLvsAscdl9kYRUREEpVUT4OZXWBmb5nZAjOba2YTzGzrBI7b3cyKzWyJmX1sZs3mq/G22+ruRTjh\nBDj+eDjtNPjvfzMSloiISNKSfTzRG7gF6AnsDbQGJptZu5oOMLPNgaeA/wA7AjcDd5nZPvWIN2eN\nHAlbbAGHHx7jIERERBqbpJIGd+/r7mPdfbq7vw8cD2wGFNRy2GnA5+5+rrt/5O4jgfHAsPoGnYtW\nXx0efTSqSJ5+OrhnOyIREZHKGjoQcm3AgR9radMLeK7KtmeAXRp47ZyzzTYxvmHsWLjnnmxHIyIi\nUlm9kwYzM+Am4FV3r622YUdgbpVtc4G1zKxNfa+fq445Bk46KcZBvP9+tqMRERFZqSE9DaOAbYGj\nUhSLlLn5Zthyy0geSkuzHY2IiEio15RLM7sV6Av0dve6CiF/C3Sosq0DsMDdl9Z24LBhw8jLy6u0\nrbCwkMLCwiQjblratYNRo6BPH7jvPhg8ONsRiYhIY1RUVERRUVGlbfPnz0/b9cyTHHFXljD0A/q4\n++cJtL8aOMDdd6yw7UFgbXfvW8Mx+UBxcXEx+fn5ScWXS449FiZNirUq1l0329GIiEhTUFJSQkFB\nAUCBu5ek8tzJ1mkYBQwEjgYWmVmHslfbCm2uNLMxFQ4bDWxhZteYWVczOx0YANyQgvhz2nXXwbJl\n8Ne/ZjsSERGR5Mc0nAqsBbwIzK7wOqJCm42ATuVv3P0L4ECirsO7xFTLE9y96owKqaJjR7j00phR\nUVyc7WhERKS5S2pMg7vXmWS4+6Bqtr1M7bUcpAZDh8b0yyFD4PXXYy0LERGRbNBXUCPXqlVUi5wy\nBe69N9vRiIhIc6akoQno3TvqN5x/PvxYWxktERGRNFLS0EQkOijy8cfhu+8yE5OIiDQvShqaiEQG\nRT7yCBx6KAzTqh4iIpIGShqakKFDYfvtY1Bk1UqRX34JJ58Mm2wCRUXw2WfZiVFERHKXkoYmpKZB\nkb/+CgMHwtprw9SpsP76cM012YtTRERyk5KGJqa6QZFXXAFvvAEPPAAbbQRnnx3lp7/+OquhiohI\njlHS0ARVHBT52mtw2WVw0UWw666x/7TToH17+PvfsxuniIjkFiUNTVDFQZEDBsAuu8CFF67cv9Za\n8Kc/wR13wLx52YtTRERyi5KGJqp8UOTixfFYolWV2p5/+lNUj7zppuzEJyIiuUdJQxPVqhU880wM\niuzcedX9660XjylGjoSff858fCIiknuUNDRhG20EXbvWvP/ss2HpUrj11szFJCIiuUtJQw7baCM4\n4QS4/voY/7BwYbYjEhGRpkxJQ467+GLo0ycKQm2ySfz5wQfZjkpERJoiJQ05bsMNYz2KmTPhzDPh\nn/+EHXaAP/8525GJiEhTo6ShmdhsM7j8cpg1K5KH0aNj5oWIiEiilDQ0M61bx6yKRYtg8uRsRyMi\nIk2JkoZmqGtX2G47eOyxbEciIiJNiZKGZuqww+DJJ6McdSotWxbjJ0REJPcoaWim+veH+fPh+efr\nbvvllzBqFPzhDzEboybusdrmNtvADz+kLlYREWkclDQ0U7/9LWy5ZcymqM7PP8Pw4THTYvPNY/Dk\n3LmxONadd1Z/zK23wvjx0dtQ03lFRKTpUtLQTJlFb8Pjj8OKFavuP+ss+Mc/oKAAHn0Uvv8epk6N\nQZRDhsArr1RuP3UqnHNOHLfnnvDQQ5n5HCIikjlKGpqx/v3hu+9WTQDefBPGjIEbboD77ouVNPPy\nYt/NN8cS3P37x2MLgJ9+gsMPh/x8uOYaOOooeOEFmDMnox9HRETSTElDM7bzzrDpppVnUZSWwhln\nwP/9X5Sgrqp16+h5aN8e+vWD//0PjjsuSlQ/8gistloMsmzVKtqJiEjuSDppMLPeZvakmX1jZqVm\ndnACxww0s3fNbJGZzTazu81s3fqFLKnSokV8wU+YEMkCRM/C22/DLbdAy5bVH7f++jHz4rPPYMcd\nYeJEuP/+KCAFsO66sN9+ekQhIpJr6tPT0B54Fzgd8Loam9muwBjgTmBbYADQA7ijHteWFOvfH775\nBt56KwY/nn9+zIDYddfaj9thBxg3Dj7/HM47Dw48sPL+wkJ44w344ou0hS4iIhnWKtkD3H0SMAnA\nzCyBQ3oBM919ZNn7L83sduDcZK8tqbfrrrE+xWOPwa+/wi+/xLiERPTrF2WpN9101X0HHwzt2sHD\nD0dSISIiTV8mxjS8AXQyswMAzKwDcDjwdAauLXVo2RIOPTQeL9xyC/z1r7EaZqI6dYqZGFWtsUbU\nddAjChGR3JH2pMHdXweOAR42s2XAHOAnYGi6ry2JOewwmDcv6jEMG5a68xYWwrvvwowZqTuniIhk\nT9KPJ5JlZtsCNwOXAJOBjYC/A7cDJ9Z27LBhw8grn+tXprCwkMLCwrTE2lztsQfstRdccAG0aZO6\n8x5wAKy1VvQ2XHJJ6s4rIiKhqKiIoqKiStvmz5+ftuuZe51jGWs+2KwUOMTdn6ylzf1AW3c/osK2\nXYFXgI3cfW41x+QDxcXFxeTn59c7Psm+44+PAZEzZlT/GENERFKrpKSEgoICgAJ3L0nluTMxpmF1\n4Ncq20qJmRf6GslxRx0FH38cjylERKRpq0+dhvZmtqOZ7VS2aYuy953K9l9lZmMqHDIR6G9mp5pZ\nl7JehpuBKe7+bYM/gTRqe+0F660Hp58eNSC+/z7bEYmISH3Vp6dhZ+AdoJjoLbgeKAEuLdvfEehU\n3tjdxwBnA0OA94GHgelA/3pHLU1G69Zwzz3xaGLwYOjQAXbbDW68EZYuzXZ0IiKSjPrUaXiJWpIN\ndx9UzbaRwMhqmkszcPDB8fr2W3jqKXjiCTj33Fi74qabsh2diIgkSmtPSMZ07Agnnhhlp//+91j8\n6tlnsx2ViIgkSkmDZMUZZ8Dee8fsih9/zHY0IiKSCCUNkhUtWsTAyMWL4ZRToAEzf0VEJEOUNEjW\nbLIJ3H47jB8PY8dmOxoREamLkgbJqsMPh2OPhaFDtSKmiEhjp6RBsu6WW2DddeG44/SYQkSkMVPS\nIFmXlwd33w0vvxxLaYuISOOkpEEahb32gkMOifoNixdnOxoREamOkgZpNK67LgpA3XBD4sc8/DCc\nc076YhIRkZWUNEijsdVWcOaZcNVVMHt23e0nTYKBAyPJeOml9McnItLcKWmQRuWvf4XVV4cLL6y9\n3TvvxMyLvn1hxx3h8sszE5+ISHOmpEEalbw8uOyyKPxUXFx9m1mz4MADYZttoKgIRoyA//wHXnst\no6GKiDQ7Shqk0TnxRNh+ezjrrFWnYP78c/QutG0ba1i0bw+HHgrbbafeBhGRdEt6lUuRdGvVKsYp\n7LsvHHNMLHS12mrxevZZmDMHXn89ltmGKEk9YgQcdRRMmQI9e2Y3fhGRXKWkQRqlffaJ6ZfPPBPj\nF5Yti1ebNrG0dteuldsPGADdukVvw1NPZSdmEZFcp6RBGq1rrolXIlq2jEGUxxwDJSWQn5/e2ERE\nmiONaZCcceSR8JvfaGyDiEi6KGmQnNGqFQwfDo8/DtOmZTsaEZHco6RBcsrAgdHbMGAAfPVVtqMR\nEcktShokp7RuHZUily+HPn203LaISCopaZCcs8UWUVa6RQvYbTf49NOV+9zh1Vehf384+eTsxSgi\n0hQpaZCc1LlzJA6rrx6JwwcfxOJWPXtC795RQfLee2HhwprP4R4zMUREJChpkJy1ySaROKy3Huyw\nQxR/WnNNePppePNN+PXX6HWoyeOPQ0EBvP125mIWEWnMkk4azKy3mT1pZt+YWamZHZzAMauZ2RVm\n9oWZLTGzz83s+HpFLJKEDh3ghRfg4oujSNR//hNlqLt2jaTi+edrPvbpp+PPsWMzE6uISGNXn56G\n9sC7wOmA19G23KPAHsAgYGugEPioHtcWSdr668Mll8BOO63cZgZ77llz0uAeAyrbtYtFsZYvz0io\nIiKNWtJJg7tPcveL3P0JwOpqb2b7A72Bvu7+grvPcvcp7v5GPeIVSZk994zehx9/XHXfBx/AN9/E\nipvffRdrXoiINHeZGNNwEPA2cJ6ZfW1mH5nZdWbWNgPXFqnRHntEj8KLL666b9KkGEQ5dGisuDlu\nXMbDExFpdDKRNGxB9DRsBxwCnAkMAEZm4NoiNercGbbcsvpHFP/+dyQVbdvGehaPP17zTIsnnoB5\n89Ibq4hIY5CJpKEFUAoc7e5vu/sk4GzgODNrk4Hri9SounENCxfGrIr994/3Rx8NS5bAP/+56vFP\nPw2HHAInnpj+WEVEsi0Tq1zOAb5x9/9V2DadGA+xKfBZTQcOGzaMvLy8StsKCwspLCxMR5zSDO25\nJ9x5J8ykKh3OAAAcXUlEQVSZAxttFNteeCEGPpYnDZ06we67xyyK445beezPP0eBqC5dYOLEWMZ7\nv/0y/hFEpBkrKiqiqKio0rb58+en7XrmnugEiGoONisFDnH3J2tpcxJwI7Chu/9Stq0fMB5Yw92X\nVnNMPlBcXFxMvtY4ljSaOxc6doQHHogeBYDTToPnnoNPPlnZ7p57ojfhq69iqibE+0cegf/+Nx5h\nfPddLJTVunXmP4eISLmSkhIKCgoACtw9pSXq6lOnob2Z7Whm5RPYtih736ls/1VmNqbCIQ8CPwD3\nmtk2ZrYbcC1wd3UJg0gmdegA22238hFF+VTL8l6Gcv37Q5s28OCD8X7yZLj7brj++uiJuPlmmDED\nbrsts/GLiGRSfcY07Ay8AxQTdRquB0qAS8v2dwQ6lTd290XAPsDawFRgLPAEMSBSJOsqjmv46KNY\n5OqAAyq3ycuDgw+OWRQLF8JJJ8Fee60cy7DTTrHt4ovh++8zGr6ISMbUp07DS+7ewt1bVnkNLts/\nyN33rHLMx+6+n7uv4e6d3f1c9TJIY7HXXjBzZrwmTYoehd13X7XdMcfAe+/BYYfBDz/AXXdFkahy\nf/tb9FRcfHHGQhcRySitPSHNXp8+sSLmCy9E0tCnT9RoqGr//WMdi+eeg2uugc03r7x/gw3gootg\n9Gh4//2MhJ5yDz0U63KIiFRHSYM0e2uvDfn58NRTUeip6niGcq1bw5//DAMGxGDJ6gwdClttBWed\nFb0ODfXOOzBlCpSWNvxcdfn5Zxg8GE44ITPXE5GmR0mDCDGuYcIEWLp01fEMFZ1/Pjz6aPRMVGe1\n1eDGG2OMxIQJNZ9n8eIYXHnWWfDaa5W/pEtLYwrnbrtFMtOrV/RqnHNOJBCpSEaq8+CDUY/iww/j\n+iIiVTVoymW6aMqlZNozz0QPQ+fOMbbB6lxVpXZ/+EOsXzF9eix6VdX550dysd56USNik02iB2PL\nLWHUqJiJ8bvfRc/GuutGojJ+fEwR7dQpkoktt1z52mmnmAnSEPn5sNlmsRbHsmXwxhsNvw8iknmN\nasqlSC76/e/j8cP++6fmi/LGG2H2bLjuulX3vfsu/P3vMGIEfP01vPJKDK585BE480zYZpvofXjt\nNTj00BhjceutsYDWCy9E2yVL4Mkno/3++8cjkY8/rn+8JSXxKOTEE+GCC6JHo7o1OUSkeVNPg0iZ\nCRPit+3OnVNzvvPPX1m/ofycv/4Ku+wSX/rFxfE4o1xpKcyfD+usk/g1fv01poj27RtjM157rX7F\npU4/PdbQ+PJLaNky7sMGG0Q9ChFpWtTTIJIBhx6auoQB4MILIwH4859XbvvHPyJZuPPOygkDxDiJ\nZBIGgFatopdh3LjoLbj88uTj/OWXqIg5aFCczywSnmefjVhFRMopaRBJkzXXjMcT48fHwMiZM+OR\nxNChMbgxlXr0iPoQV1wBr7+e3LGPPgoLFsTMiXIDBkQyctVVqY1TRJo2PZ4QSSP3GC8xf34Mdpw+\nPdaqWHPN1F/r119jxsW338YaGIleo3fvWAL82Wcrb7/zTjjllJhN0a1b6uMVkfTQ4wmRJsoMbrkl\nvngnT46ZEelIGCAeLYwdGwtnnZlgkfYZM2IZ8OqW9v7jH2Plz2uuSW2cItJ0KWkQSbP8fLjkEhg2\nLKZiptOWW8a4iXvvhX/+s+72d98dUzoPOWTVfW3awNlnx3iJa6+NFT5FpHlT0iCSARddBDfckJlr\nHX88HHgg/OUv8ciiJsuWwZgx0aPQpk31bU49FY48MsZLdO4ca3LccQf89FPtMXz1VVSWnDWrvp9C\nRBojJQ0iOcYsFs/6/POVS3lXZ8KEeJRxwgk1t2nfPnoa5s6N3os2baKE9nbb1dzzsHw5HHUU3HMP\n7LMPzJvXsM8jIo2HkgaRHLTTTrGU99/+BitWrLp/8eIo4rTvvrD99nWfb6214LjjonLmzJlRC6Jf\nP1i0aNW2I0bAW29FsrFgAey3X6xr0VQtXgxHHBGDWEWaOyUNIjlqxAj45BN4+OFV9111VVSYvOWW\n5M+72WZRjfLjj+NRSMV1M/797xg4eeWVMHBgzMj48st4XFJdgtEUPPxwTEv9+9+zHYlI9ilpEMlR\nO+8clSL/9rfKX+wffxxf7OeeC1tvXb9z77hjzNQYP35lQamvv47xEX37xuJaEL0YkybBe+9F+eul\nSxv2mbJh1KjoWXnooeg5EWnOlDSI5LARI6Jb/bHH4r07DBkSNSOGD2/YuQ89NBKSSy6JL9TCwhjz\nMGZM5VVAe/SInomXXoKTT27YNTNt6tR4/eMfkfDUNkZEpDlQ0iCSw3r1inELl18evQ2PPALPPRcL\nYFW3+mayhg+PQY+FhbEq5kMPwfrrr9pujz3gppuid+Kzzxp+3VRZujTirsnIkTFr5KSTYrrs7ben\nb2lykaZASYNIjrvoInj//fjCHjYsegj69k3Nuc1ilsRBB8XiXL//fc1tjzsu1tYYNSo1106FCy+M\nJcgnTlx13w8/RBJ06qmxiNdJJ8UKpVqPQ5ozJQ0iOW7XXeM3/cGD45n8zTen9vzt2sXjhyFD6m53\n4omRZDSGQZFz5kRPQl5exPXdd5X333NP9CqUT0ndf3/YdNOoUyHSXClpEGkGLrooHk9cfDF06pS9\nOE4/PRKXcePSf63S0soDQKu66qpYc+PNN2Na6imnrHz0sGIF3HZbTLXcYIPY1rJlJBcPPggLF6Y/\nfpHGSEmDSDOw++6xzkTFZbqzoXPnqB9x663pHxtw9NHxuGTx4lX3ffVVjE/4859jMa7bb49iV+XJ\nzKRJUY+iau/J4MFxvoceSm/sIo2VkgaRZqJr1xiDkG1Dh8IHH8RsinR5+eWorzBlSoxJqJqgXHFF\nLBz2pz/F+/794dhjI7ZZs2LcRX4+9OxZ+bhOnWI8SNVHFC+9FNNLTzklfZ9JpDFQ0iAiGbXnnrDN\nNvUrLFVuzpzqK11CJAjnnQcFBTH48/77Y8pkuZkzY6Gu886rvOLoP/4RlS8POyyKVA0ZUn2SdfLJ\n8PbbUFISgyUHD46enCVLIpn4z3+S+yyLFkXpbZGmIOmkwcx6m9mTZvaNmZWa2cFJHLurmS03s5Su\n7y0iTYdZ/Eb/+OP1W9Dq449hiy3gmGOqf8Txz3/GOIVrr41HFH/+cxSbeuGF2H/55bDeeqs+elh7\nbbjvvpgdsfbaMZW0OgccABtvHL0U3brFY4077oCPPoLevWNtjiVLEvssy5dHctOtWwwm1XROaezq\n09PQHngXOB1I+K+4meUBY4Dn6nFNEckhf/wjrLEGjB6d3HHu8bihffsYV3DttZX3L18ea2rsv3/0\naEAMeNxjjxjU+Nxz0fNwwQWw+uqrnn+vvaIH5MYbq98P0KpVTL987TXYe+8onnXSSTFQcvRo+OIL\nuPrqxD7PuHGRbGyySazlceCBUfq73Lx5kZDst18kK+qRkKxz93q/gFLg4ATbFgGXAhcDJXW0zQe8\nuLjYRSQ3nXmm+/rruy9enPgx997rDu6TJ7sPH+5u5v700yv333ZbbHv33crHff+9e5cu7i1auG+y\nSXLXrM7Spe7vvVf9vuHD3VdbzX3GjNrPsWyZ+xZbuB92mHtpqfuECe6dO8exp5zi3qdPxNuihftu\nu8WfV1zRsLileSguLnbil/p8b8B3fHWvjCQNwCDgTaJnQ0mDiPhHH8W/QEce6f7KK/HFWZt589zX\nXdd94MB4v2KF+x/+4J6XF1/QCxe6d+jgfuyx1R8/bZr72mu733NPaj9HVb/8EsnAnnvW/pnuuSc+\nf8UE55df3C++2H2DDdz339/9zjvjc7u7n3deJBQffpjW8CUHpDNpMG/AQzQzKwUOcfcna2nzG+Bl\n4Pfu/pmZXQz0c/f8Wo7JB4qLi4vJz6+xmYg0cbfcEqtHzpoFXbrEOIVjj4Xf/GbVtn/8Izz9dDwO\n2HDD2DZ/fpTKdo8yz7fcEmMeOneu/nrLl8fiU+k2eXI8Urj//vg81cXRrVssYV6+LkhdFi+O9uuu\nC6++Go9DRKpTUlJCQUEBQIG7p3QMYVqTBjNrQfQw3OXud5Rtu4Tonagzadhtt93Iy8urtK+wsJDC\nwsJ6xywijUtpKbzySsx0ePTRKP502GGx2NZOO0Wb556DffaJWQ+DB1c+/uOPY1Gs+fNjwGNjWcK6\nsDDinjYtBk5WdM89UWly2jT47W8TP+err8Juu8ENN8BZZ9XdfsWKeK22WnKxS9NRVFREUVFRpW3z\n58/n5ZdfhjQkDWl9PAHklbVZBiwve62osG33Go7T4wmRZuiXX9zvvtt9yy2j6/7gg+PRxVZbxXP9\nmrr7n3kmxgB8/31Gw63VnDkxfqJjR/dXX125fdmyGF/Rv3/9zjt0qHu7du6fflp329NPdy8oqN91\npOlK5+OJdNdpWABsD+wE7Fj2Gg3MKPvvKWm+vog0Ie3aRU/CjBnRtT9jRkxjnDUrqjbWVJxq333h\nxRdjKmVj0bFj1HP4zW+ijkN5FcyxY6NWxEUX1e+8V10Vj2dOOqn2KZqffBL3rLgY/vvf+l1LpKpW\nyR5gZu2BrYDy/323MLMdgR/d/SszuwrY2N2Pc3cHPqxy/DxgibtPb2DsIpKjWrWKsQBHHw3jx8ca\nEd26ZTuq5HXsGMWezj0XzjgD3norHjH075/cY4mK1lgD7rwzEqXbb48pqNW5+OK4/sKF8dhnu+3q\n/zkSVVoaj0MyMW5EsqM+PQ07A+8AxUT3x/VACTGdEqAjkMUlcUQkV7RsCUceGTUMmqrWraPuw4MP\nRgI0c2Z8oTfEPvtEZcpzzqlc16Hce+9FHYuLLop79+ijDbteIoqLYdttY8yF6knkrqSTBnd/yd1b\nuHvLKq/BZfsHufuetRx/qdcyCFJEJBcVFsLUqfDII7DDDg0/3/XXxwDLY45Z9Ut6xIiomjloUBS1\n+vDD9D2iWLEiiln16hUDLqdOhb/9LT3Xam5mzoRffsl2FJVp7QkRkQzZbjs4/PDUnGuNNaKiZHFx\n5S/pKVOiJPUll0Qvxz77QF5eJCupNmtWVN4cPjzKdb/9dvRuXHFFlPKuryVLohz3rbfG+h6JKi2N\nKaw//lj/azcW330Xf1+6doWiosZTYlxJg4hIE9Wz58ov6TfeiG0XXhhfNuUz09u0WfmIIpVfPOPH\nx7iMmTNjXY+rroqehuHDYz2NY4+Nxbjq46qrYtzGsGGw0UYxBmTixLofezzyCAwYEJ//iSfqd+1k\npevL/N57IwkqKIixPb17R4KYbUoaRESasOHDoXv3+JKeODEGXl5+eeXiT0ccEUWxUvGIYsmSWHDs\n8MOjF2PaNOjTZ+X+Vq1ihsjs2dH7kKwZMyJpGD4cvvkm1hf57DM4+OAYM/Hzz9Uft2xZJEx77QU7\n7wyHHAIDBybXU5GMFSvg0kthnXViKfZUn3v06BjP8/jjUe9j/vz4OZ92WiQTWZPqOZypeKE6DSIi\nCfv0U/f27d1btXLfeedV61ksXRrlti+6qGHX+eQT9//7vyhnPWpU7WWyb7stam1UXBukLqWlUY9j\nq61WXR9k6lT3Ndd0P/HE6o+99dZYd+T99+M8Y8e6r7OO+4Ybuk+cmHgMifj665Vrg3Tp4r7ppu4/\n/JC68z/9dNy7N99cuW35cvfrrovtL7xQ+/GNdu2JdL2UNIiIJOeee+JLc/Lk6vcfd5x7t26rftE/\n9lh88V12mfv8+dUfu3x5fAmvuWYU3krkn+bSUvcDDoj1QGbPTvwzgPtzz1W/f/To6vcvWBDJwfHH\nV94+e3bE0KaN+48/JhZDXSZOdF9vPfeNN3Z/8UX3WbMiOTn00LrXT0nUgQe65+ever7S0vhZ1ZQ4\nlVPSICIidZo7t+Z9Tz0V/+K///7KbU88Eb0TBQXxxbreeu7XXuu+aFHsnzEjFsraaKM49ogjak4s\nqjN7dlTE3HDDuFZtyhckq2nBMfdYpKxPn/ji/N//Vm6/5JKI/8svVz1mzhz3li3dR45MPO6aXHhh\n3IcDD3T/7ruV2//5z9g+enTDrzFzZiR/d91Vcwx5ebWv1KqkQUREGqT8EcWIEfH+6afdW7eOctbL\nl8dvzKecEklEhw7uu+wS3xDrrOM+ZIj722/X77rffut+0EFxrsGDa046/vjHSBrKV/WsySefuLdt\n6z5s2Mrzr7GG+znn1HzMQQfFY5uG+Ne/4jNcfnn1PQqnnRZxffBBw65z/vnxc6qYFFX04YcRx2OP\n1XwOJQ0iItJgxx3n3rVrrNXRpo17v36xFkZFn33mfsIJ8dv0Qw/V/httokpLY02RNdZw33xz98cf\nd3/jjViT46WX4rdqiDaJuO66+G38jTdiLY68vNrXHSnvCajYy5KMBQvcO3Vy32efmh9B/PKL+3bb\nuW+/ffx3fSxZ4r7++u5nnll7u/x898MOq3m/kgYREWmw8gF2rVu79+0bX1KZ9Pnn7r17RwxVX3vt\nlfiYgOXLo+dgyy3js1x1Ve3tly6NL+Ozz65f3EOGxEDTmTNrb/f++9Hb0K+f+/PPr5qQ1WXcuLgX\nM2bU3u7662Mw6k8/Vb+/KS9YJSIijcTee8d6FLvvHkWQ2rTJ7PW7dImaDh98AO+/H5UqP/oIPv0U\nJk2qeUGyqlq1imXSv/wSNtgA/vSn2tuvtlpMvxw3LvkS16+8AiNHwpVXwuab1952++1j2fOpU6Po\n1frrx7TJceMSm/p5221xXNeutbc76qj4HI89lvDHSBlzbyRlpiows3yguLi4mPx8VZwWEUmVn36K\nCpEtcuBXxieeiKThd7+ru+20abDTTnHMwQcndv4lS2DHHWP11FdeqVz7ojbu8M47UTfjqaeiUmaL\nFhHnQQfFq1u3yklSeXzjx0cxq7rsvXfUa3j++VX3lZSUUFBQAFDg7iWJRZ0YJQ0iItIs5OdD584w\nYUJi7YcPjzU+3nknCkvV1+zZ8K9/RRLx7LOweHFUumzZMhKTJUtijYkOHaL3JJFVQu+9F044Ab76\nCjbZpPK+dCYNSS+NLSIi0hQNGgRnnw3z5sGGG9betqQkqlFecknDEgaIhcVOPDFeixdH78Drr0fS\n0K5dLP3erl2UBU90WfHDDovqkEVF9au8WV/qaRARkWbhhx/iC/zqq2Ndi5p89x306BEloqdMSfyL\nPNMOPzyWRn/33crb09nTkANPtUREROq23noxnuHee2teaGrpUjj00HhcMGFC400YIAZ3TpuWvmXP\nq6OkQUREmo1Bg2LmRkk1v3+7w8knx8DFxx+P8Q+N2QEHRG/IAw9k7ppKGkREpNnYd98YOHjEEbH8\n9tKlK/dddx3cf39M59xll+zFmKg2bWJK55dfZu6aShpERKTZaNUKnnkmZlKcckrUXrj22vht/fzz\nY3ntgQOzHWXibr01sz0Nmj0hIiLNynbbwaOPwscfR+/CiBGwbFnUR7jssmxHl5xEa0ekinoaRESk\nWdp663hEMXMmjB4djyZyoehVOqmnQUREmrWNN45HFVI35VQiIiKSECUN8v8VFRVlO4RmR/c883TP\nM0/3PHcknTSYWW8ze9LMvjGzUjOrdekPMzvUzCab2Twzm29mr5vZvvUPWdJF/2Nnnu555umeZ57u\nee6oT09De+Bd4HRive667AZMBg4A8oEXgIlmtmM9ri0iIiJZkvRASHefBEwCMKt79XN3r1rh+0Iz\n6wccBExL9voiIiKSHRkf01CWaKwJ/Jjpa4uIiEj9ZWPK5V+IRxyP1NKmLcD06dMzEpCE+fPnU1Jd\nQXZJG93zzNM9zzzd88yq8N3ZNtXnbtDS2GZWChzi7k8m2P5o4HbgYHd/oY52GSyMKSIiknMGuvuD\nqTxhxnoazOwo4A5gQG0JQ5lngIHAF8CSNIcmIiKSS9oCmxPfpSmVkaTBzAqBu4AjywZS1srdfwBS\nmh2JiIg0I6+n46RJJw1m1h7YCiifObFF2fTJH939KzO7CtjY3Y8ra380cB/wJ2CqmXUoO26xuy9o\n6AcQERGRzEh6TIOZ9SFqLVQ9cIy7Dzaze4HO7r5nWfsXiFoNVY1x98H1iFlERESyoEEDIUVERKT5\n0NoTIiIikhAlDSIiIpKQRpc0mNkQM5tpZovN7E0z657tmHKFmV1gZm+Z2QIzm2tmE8xs62raXWZm\ns83sFzN71sy2yka8ucbMzi9b5O2GKtt1v1PMzDY2s7Fm9n3ZfZ1mZvlV2ui+p4iZtTCzy83s87L7\n+amZ/bWadrrn9ZTIYpF13V8za2NmI8v+v1hoZuPNbMNk4mhUSYOZHQlcD1wM/B+xNsUzZrZ+VgPL\nHb2BW4CewN5Aa2CymbUrb2Bm5wFDgZOBHsAi4mewWubDzR1lye/JVFlvRfc79cxsbeA1YCmwH7AN\ncA7wU4U2uu+pdT5wCrGQYTfgXOBcMxta3kD3vMFqXSwywft7E3Ag0J+YoLAx8FhSUbh7o3kBbwI3\nV3hvwNfAudmOLRdfwPpAKfD7CttmA8MqvF8LWAwcke14m+oLWAP4CNiTmHl0g+53Wu/31cBLdbTR\nfU/tPZ8I3Fll23jgft3ztNzvUqKycsVttd7fsvdLgUMrtOladq4eiV670fQ0mFlroAD4T/k2j0/1\nHLBLtuLKcWsTGeuPAGbWBehI5Z/BAmAK+hk0xEhgors/X3Gj7nfaHAS8bWaPlD2GKzGzE8t36r6n\nxevAXmb2G4Cy2j27Av8qe697nkYJ3t+didpMFdt8BMwiiZ9BNhasqsn6QEtgbpXtc4lsSFKobLXR\nm4BX3f3Dss0diSSiup9BxwyGlzPKyqfvRPwPW5Xud3psAZxGPOq8guiq/YeZLXX3sei+p8PVxG+y\nM8xsBfHo+0J3f6hsv+55eiVyfzsAy3zVoopJ/QwaU9IgmTUK2Jb4bUDSwMw2JRKzvd19ebbjaUZa\nAG+5+4iy99PMbHvgVGBs9sLKaUcCRwNHAR8SifLNZja7LFGTHNFoHk8A3wMriGyoog7At5kPJ3eZ\n2a1AX2B3d59TYde3xDgS/QxSowDYACgxs+VmthzoA5xpZsuIDF/3O/XmANOrbJsObFb23/p7nnrX\nAle7+6Pu/l93fwC4EbigbL/ueXolcn+/BVYzs7VqaVOnRpM0lP0mVgzsVb6trAt9L9K08EZzVJYw\n9AP2cPdZFfe5+0ziL0/Fn8FaxGwL/QyS9xywA/Fb145lr7eBccCO7v45ut/p8BqrPtLsCnwJ+nue\nJqsTv/RVVErZd4zueXoleH+LgV+rtOlKJNNvJHqtxvZ44gbgPjMrBt4ChhF/Ge/LZlC5wsxGAYXA\nwcCiCouHzXf38iXIbwL+amafEkuTX07MYHkiw+E2ee6+iOiq/f/MbBHwg7uX/yas+516NwKvmdkF\nwCPEP5wnAidVaKP7nloTifv5NfBfIJ/49/uuCm10zxvA6lgskjrur7svMLO7gRvM7CdgIfAP4DV3\nfyvhQLI9daSaqSSnl33gxUT2s3O2Y8qVF5H5r6jm9ccq7S4hpu/8QqzHvlW2Y8+VF/A8FaZc6n6n\n7T73Bd4ru6f/BQZX00b3PXX3uz3xS99Moj7AJ8ClQCvd85Td4z41/Bt+T6L3F2hD1Or5vixpeBTY\nMJk4tGCViIiIJKTRjGkQERGRxk1Jg4iIiCRESYOIiIgkREmDiIiIJERJg4iIiCRESYOIiIgkREmD\niIiIJERJg4iIiCRESYOIiIgkREmDiIiIJERJg4iIiCTk/wHMztUCX24OVgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x106d23ac8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as ticker\n",
    "%matplotlib inline\n",
    "\n",
    "plt.figure()\n",
    "plt.plot(all_losses)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Evaluating the Results\n",
    "\n",
    "To see how well the network performs on different categories, we will create a confusion matrix, indicating for every actual language (rows) which language the network guesses (columns). To calculate the confusion matrix a bunch of samples are run through the network with `evaluate()`, which is the same as `train()` minus the backprop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n55xzrg78fziXG3mmK1+9AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1105fd630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Keep track of correct guesses in a confusion matrix\n",
    "confusion = torch.zeros(n_categories, n_categories)\n",
    "n_confusion = 10000\n",
    "\n",
    "# Just return an output given a line\n",
    "def evaluate(line_tensor):\n",
    "    hidden = rnn.init_hidden()\n",
    "    \n",
    "    for i in range(line_tensor.size()[0]):\n",
    "        output, hidden = rnn(line_tensor[i], hidden)\n",
    "    \n",
    "    return output\n",
    "\n",
    "# Go through a bunch of examples and record which are correctly guessed\n",
    "for i in range(n_confusion):\n",
    "    category, line, category_tensor, line_tensor = random_training_pair()\n",
    "    output = evaluate(line_tensor)\n",
    "    guess, guess_i = category_from_output(output)\n",
    "    category_i = all_categories.index(category)\n",
    "    confusion[category_i][guess_i] += 1\n",
    "\n",
    "# Normalize by dividing every row by its sum\n",
    "for i in range(n_categories):\n",
    "    confusion[i] = confusion[i] / confusion[i].sum()\n",
    "\n",
    "# Set up plot\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "cax = ax.matshow(confusion.numpy())\n",
    "fig.colorbar(cax)\n",
    "\n",
    "# Set up axes\n",
    "ax.set_xticklabels([''] + all_categories, rotation=90)\n",
    "ax.set_yticklabels([''] + all_categories)\n",
    "\n",
    "# Force label at every tick\n",
    "ax.xaxis.set_major_locator(ticker.MultipleLocator(1))\n",
    "ax.yaxis.set_major_locator(ticker.MultipleLocator(1))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can pick out bright spots off the main axis that show which languages it guesses incorrectly, e.g. Chinese for Korean, and Spanish for Italian. It seems to do very well with Greek, and very poorly with English (perhaps because of overlap with other languages)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Running on User Input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "> Dovesky\n",
      "(-0.87) Czech\n",
      "(-0.88) Russian\n",
      "(-2.44) Polish\n",
      "\n",
      "> Jackson\n",
      "(-0.74) Scottish\n",
      "(-2.03) English\n",
      "(-2.21) Polish\n",
      "\n",
      "> Satoshi\n",
      "(-0.77) Arabic\n",
      "(-1.35) Japanese\n",
      "(-1.81) Polish\n"
     ]
    }
   ],
   "source": [
    "def predict(input_line, n_predictions=3):\n",
    "    print('\\n> %s' % input_line)\n",
    "    output = evaluate(Variable(line_to_tensor(input_line)))\n",
    "\n",
    "    # Get top N categories\n",
    "    topv, topi = output.data.topk(n_predictions, 1, True)\n",
    "    predictions = []\n",
    "\n",
    "    for i in range(n_predictions):\n",
    "        value = topv[0][i]\n",
    "        category_index = topi[0][i]\n",
    "        print('(%.2f) %s' % (value, all_categories[category_index]))\n",
    "        predictions.append([value, all_categories[category_index]])\n",
    "\n",
    "predict('Dovesky')\n",
    "predict('Jackson')\n",
    "predict('Satoshi')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The final versions of the scripts [in the Practical PyTorch repo](https://github.com/spro/practical-pytorch/tree/master/char-rnn-classification) split the above code into a few files:\n",
    "\n",
    "* `data.py` (loads files)\n",
    "* `model.py` (defines the RNN)\n",
    "* `train.py` (runs training)\n",
    "* `predict.py` (runs `predict()` with command line arguments)\n",
    "* `server.py` (serve prediction as a JSON API with bottle.py)\n",
    "\n",
    "Run `train.py` to train and save the network.\n",
    "\n",
    "Run `predict.py` with a name to view predictions: \n",
    "\n",
    "```\n",
    "$ python predict.py Hazaki\n",
    "(-0.42) Japanese\n",
    "(-1.39) Polish\n",
    "(-3.51) Czech\n",
    "```\n",
    "\n",
    "Run `server.py` and visit http://localhost:5533/Yourname to get JSON output of predictions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercises\n",
    "\n",
    "* Try with a different dataset of line -> category, for example:\n",
    "    * Any word -> language\n",
    "    * First name -> gender\n",
    "    * Character name -> writer\n",
    "    * Page title -> blog or subreddit\n",
    "* Get better results with a bigger and/or better shaped network\n",
    "    * Add more linear layers\n",
    "    * Try the `nn.LSTM` and `nn.GRU` layers\n",
    "    * Combine multiple of these RNNs as a higher level network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Next**: [Generating Shakespeare with a Character-Level RNN](https://github.com/spro/practical-pytorch/blob/master/char-rnn-generation/char-rnn-generation.ipynb)"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "celltoolbar": "Raw Cell Format",
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
